Passed
Push — master ( 13b350...038bd4 )
by Rafael S.
03:46
created

alaw.js ➔ decodeSample   A

Complexity

Conditions 4

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 16
dl 0
loc 22
rs 9.6
c 0
b 0
f 0
1
/*
2
 * alawmulaw: A-Law and mu-Law codecs in JavaScript.
3
 * https://github.com/rochars/alawmulaw
4
 *
5
 * Copyright (c) 2018 Rafael da Silva Rocha.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining
8
 * a copy of this software and associated documentation files (the
9
 * "Software"), to deal in the Software without restriction, including
10
 * without limitation the rights to use, copy, modify, merge, publish,
11
 * distribute, sublicense, and/or sell copies of the Software, and to
12
 * permit persons to whom the Software is furnished to do so, subject to
13
 * the following conditions:
14
 *
15
 * The above copyright notice and this permission notice shall be
16
 * included in all copies or substantial portions of the Software.
17
 *
18
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
 *
26
 */
27
28
/**
29
 * @fileoverview A-Law codec.
30
 * @see https://github.com/rochars/wavefile
31
 * @see https://github.com/rochars/alawmulaw
32
 */
33
34
/** @type {!Array<number>} */
35
const LOG_TABLE = [
36
  1,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, 
37
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, 
38
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, 
39
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 
40
];
41
42
/**
43
 * Encode a 16-bit linear PCM sample as 8-bit A-Law.
44
 * @param {number} sample A 16-bit PCM sample
45
 * @return {number}
46
 */
47
export function encodeSample(sample) {
48
  /** @type {number} */
49
  let compandedValue; 
50
  sample = (sample ==-32768) ? -32767 : sample;
51
  /** @type {number} */
52
  let sign = ((~sample) >> 8) & 0x80; 
53
  if (!sign) {
54
    sample = sample * -1; 
55
  }
56
  if (sample > 32635) {
57
    sample = 32635; 
58
  }
59
  if (sample >= 256)  {
60
    /** @type {number} */
61
    let exponent = LOG_TABLE[(sample >> 8) & 0x7F];
62
    /** @type {number} */
63
    let mantissa = (sample >> (exponent + 3) ) & 0x0F; 
64
    compandedValue = ((exponent << 4) | mantissa); 
65
  } else {
66
    compandedValue = sample >> 4; 
67
  } 
68
  return compandedValue ^ (sign ^ 0x55);
69
}
70
71
/**
72
 * Decode a 8-bit A-Law sample as 16-bit PCM.
73
 * @param {number} aLawSample The 8-bit A-Law sample
74
 * @return {number}
75
 */
76
export function decodeSample(aLawSample) {
77
  /** @type {number} */
78
  let sign = 0;
79
  aLawSample ^= 0x55;
80
  if ((aLawSample & 0x80) !== 0) {
81
    aLawSample &= ~(1 << 7);
82
    sign = -1;
83
  }
84
  /** @type {number} */
85
  let position = ((aLawSample & 0xF0) >> 4) + 4;
86
  /** @type {number} */
87
  let decoded = 0;
88
  if (position != 4) {
89
    decoded = ((1 << position) |
90
      ((aLawSample & 0x0F) << (position - 4)) |
91
      (1 << (position - 5)));
92
  } else {
93
    decoded = (aLawSample << 1)|1;
94
  }
95
  decoded = (sign === 0) ? (decoded) : (-decoded);
96
  return (decoded * 8) * -1;
97
}
98
99
/**
100
 * Encode 16-bit linear PCM samples as 8-bit A-Law samples.
101
 * @param {!Int16Array} samples A array of 16-bit PCM samples.
102
 * @return {!Uint8Array}
103
 */
104
export function encode(samples) {
105
  /** @type {!Uint8Array} */
106
  let aLawSamples = new Uint8Array(samples.length);
107
  for (let i = 0, len = samples.length; i < len; i++) {
108
    aLawSamples[i] = encodeSample(samples[i]);
109
  }
110
  return aLawSamples;
111
}
112
113
/**
114
 * Decode 8-bit A-Law samples into 16-bit linear PCM samples.
115
 * @param {!Uint8Array} samples A array of 8-bit A-Law samples.
116
 * @return {!Int16Array}
117
 */
118
export function decode(samples) {
119
  /** @type {!Int16Array} */
120
  let pcmSamples = new Int16Array(samples.length);
121
  for (let i = 0, len = samples.length; i < len; i++) {
122
    pcmSamples[i] = decodeSample(samples[i]);
123
  }
124
  return pcmSamples;
125
}
126